package org.jmc.refmanager.web.wicket.page.validation;

import java.util.Date;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.apache.wicket.MarkupContainer;
import org.apache.wicket.PageParameters;
import org.apache.wicket.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.datetime.markup.html.basic.DateLabel;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.jmc.refmanager.domain.dao.QueryParam;
import org.jmc.refmanager.domain.model.Change;
import org.jmc.refmanager.domain.model.Change.Operation;
import org.jmc.refmanager.domain.model.Change.TaskStatus;
import org.jmc.refmanager.domain.model.User;
import org.jmc.refmanager.domain.service.ChangeManager;
import org.jmc.refmanager.domain.service.UserManager;
import org.jmc.refmanager.domain.service.exception.BusinessException;
import org.jmc.refmanager.security.SecurityHelper;
import org.jmc.refmanager.web.wicket.markup.html.navigation.paging.CustomPagingNavigator;
import org.jmc.refmanager.web.wicket.model.EnumPropertyModel;
import org.jmc.refmanager.web.wicket.page.template.TemplatePage;
import org.jmc.refmanager.web.wicket.provider.MyTasksSortableDataProvider;

/**
 */
@AuthorizeInstantiation(value={"ROLE_APPROVER"})
public class MyTasksListPage extends TemplatePage {
	@SpringBean(name="taskManager")
	private ChangeManager taskManager;

	@SpringBean(name="userManager")
	private UserManager userManager;
	
	final QueryParam<Change> queryParams = new QueryParam<Change>();
	
	/**
	 * 
	 */
	public MyTasksListPage() {
		super();
		initComponent(null);
	}

	/**
	 * @param parameters
	 */
	public MyTasksListPage(PageParameters parameters) {
		super(parameters);
		initComponent(parameters);
	}

	/**
	 * 
	 * @param parameters
	 */
	private void initComponent(PageParameters parameters) {
		add(new Label("pageTitle", "Mon panier de tâches"));
		
		final String matricule = SecurityHelper.getAuthentication().getName();
		
		MyTasksSortableDataProvider dp = new MyTasksSortableDataProvider(this.queryParams);

        final DataView<Change> dataView = new DataView<Change>("changes", dp) {
			private static final long serialVersionUID = 1L;

			@Override
		    public boolean isVisible() {
				return this.getItemCount() > 0;
			}

			@Override
			protected void populateItem(Item<Change> item) {
				final Change task = item.getModelObject();

				item.add(new Label("type", 
						new EnumPropertyModel<Operation>(task, "operation", this, Operation.class)));
				item.add(new Label("status", 
						new EnumPropertyModel<TaskStatus>(task, "status", this, TaskStatus.class)));
				item.add(new Label("authorName", task.getAuthorName()));
				item.add(DateLabel.forDatePattern("creationDate", 
						new PropertyModel<Date>(task, "creationDate"), "dd/MM/yyyy"));

				// Actions
				MarkupContainer actions = new MarkupContainer("actions") {
					private static final long serialVersionUID = 1L;
				};
				item.add(actions);

				Link<Integer> unlockLink = new Link<Integer>("unlockLink", new PropertyModel<Integer>(task, "id")) {
					private static final long serialVersionUID = 1L;
		
					@Override
					public void onClick() {
						try {
							PageParameters params = new PageParameters();
							params.add("id", getDefaultModelObjectAsString());
							
							// Appel e la couche de service
							User approver = userManager.getByMatricule(matricule);
							taskManager.revert(task, approver);
							
							getSession().info("La tâche a été libérée avec succès. Elle a été retirée de votre panier.");
							setResponsePage(MyTasksListPage.class, params);
						} catch (ConstraintViolationException e) {
							error("La demande de création de service n'a pas été prise en compte.");
							Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
							for (ConstraintViolation<?> constraintViolation : violations) {
								error(constraintViolation.getMessage());
							}
							setResponsePage(MyTasksListPage.this);
						} catch (BusinessException be) {
							error(be.getMessage());
							setResponsePage(MyTasksListPage.this);
						}
					}
				};
				unlockLink.setVisible(task.getStatus() == TaskStatus.RESERVED);
				actions.add(unlockLink);

				Link<Integer> validateLink = new Link<Integer>("validateLink", new PropertyModel<Integer>(task, "id")) {
					private static final long serialVersionUID = 1L;
		
					@Override
					public void onClick() {
						try {
							PageParameters params = new PageParameters();
							params.add("id", getDefaultModelObjectAsString());
							switch (task.getOperation()) {
							case CREATE:
								setResponsePage(TaskEditNewChangePage.class, params);
								break;
	
							case MOVE:
							case DELETE:
								setResponsePage(TaskEditMoveOrDeletePage.class, params);
								break;
								
							default:
								setResponsePage(TaskEditPage.class, params);
								break;
							}
						} catch (ConstraintViolationException e) {
							error("La demande de création de service n'a pas été prise en compte.");
							Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
							for (ConstraintViolation<?> constraintViolation : violations) {
								error(constraintViolation.getMessage());
							}
							setResponsePage(MyTasksListPage.this);
						} catch (BusinessException be) {
							error(be.getMessage());
							setResponsePage(MyTasksListPage.this);
						}
					}
				};
				validateLink.setVisible(task.getStatus() == TaskStatus.RESERVED);
				actions.add(validateLink);
				
			}
		};
		dataView.setItemsPerPage(25);
        add(dataView);

		add(new CustomPagingNavigator("navigator", dataView) {
			private static final long serialVersionUID = 1L;

			@Override
		    public boolean isVisible() {
		        return dataView.getItemCount() > 0;
		    }
		});
	}
}

